<?php
require_once(dirname(__FILE__) . '/../../includes/spip_launcher.php');
include_spip('functions/pdk_common');
//include_spip('functions/spip_bonux_fonctions');
require_once(_DIR_PLUGIN_PDK.'classes/simpletest/class.PdkTest.php');
require_once _DIR_PLUGIN_EXCEL."pear/Spreadsheet/Excel/Reader.php";

class TestClassProductExcel extends PdkTest {
    /**
     * ProductExcel
     */
    private $p_ex;
    
    /**
     * ProductModel
     */
    private $prod_mdl;
    
    /**
     * PdkRubriqueModel
     */
    private $rub_mdl;
    
    /**
     * PdkArticleModel
     */ 
    private $art_mdl;
    
    /**
     * PdkMotLienModel
     */
    private $mot_lien_mdl;
    
    public function __construct(){
        parent::__construct();
        
        // Define all additional models:
        $pdk_models = array();
        $this->prod_mdl = pdk_load_class('ProductModel','classes');
        $pdk_models['ProductModel'] = $this->prod_mdl;
        $this->rub_mdl = pdk_load_class('PdkRubriqueModel','classes/models');
        $pdk_models['PdkRubriqueModel'] = $this->rub_mdl;        
        $this->art_mdl = pdk_load_class('PdkArticleModel','classes/models');
        $pdk_models['PdkArticleModel'] = $this->art_mdl;
        $this->mot_lien_mdl = pdk_load_class('PdkMotLienModel','classes/models');
        $pdk_models['PdkMotLienModel'] = $this->mot_lien_mdl;
        
        $this->AddPdkModels($pdk_models);
        
        $this->p_ex = pdk_load_class('ProductExcel', 'classes');
        
        $this->dropTestTables = ECATALOGUE_TESTS_DROP_TEST_TABLES;
    }
    
    /**
     *  Run before each test
     */
    function setUp() {
       parent::setUp();
       
       // By default we will download products from all rubriques
       $this->p_ex->DownloadRubriques = array(1,2,3,4);
       
       // By default we will download products without taking to account any id_mot 
       $this->p_ex->DownloadIdMot = false;
    }
    
    /**
     *  Run after each test
     */
    function tearDown() {
       parent::tearDown();
    }
    
    function __destruct() {       
       parent::__destruct();
    }
    
    /**
     *  This function is testing main excel document creation logic
     */
     //TODO: Refactor this test
    function TestBackupExcel() {
        $filename = 'products_test.xls';
        $this->p_ex->DownloadIdMot = 1; // We will create file with articles, that are connected with id_mot=1
        $this->p_ex->DownloadRubriques = array(1); // We will create file with articles, that lie in rubrique 1
        $this->p_ex->BackupExcel($filename);
        $full_path = $this->p_ex->GetTmpDir().$filename;
        $this->assertTrue(file_exists($full_path),'Excel file hasn\'t been created!');
        
        $reader = new Spreadsheet_Excel_Reader();
        $reader->setUTFEncoder('iconv');        
        $reader->setOutputEncoding('UTF-8');
        $reader->read($full_path);        
        $this->assertEqual(1, count($reader->sheets)); // Document must contain 1 sheet        
        $rows = $reader->sheets[0]["cells"];
        $this->assertEqual(3, count($rows)); // Document must contain 1 heading + 1 data = 2 rows
        if (file_exists($full_path))
            unlink($full_path);
    }
    
    function TestupdateProductsFromExcel_Simple() {
        // Create Excel file using BackupExcel method
        $filename = 'products_test.xls';
        $this->p_ex->BackupExcel($filename);
        
        //Update some articles and products in database so later we can see changes from Excel
        $this->art_mdl->update_by_id(1, array('titre'=>'Article 1111'));
        $this->art_mdl->update_by_id(2, array('titre'=>'Article 2222'));
        $this->prod_mdl->update_by_id(1, array('sku'=>'Change1', 'quantity'=>'999','price'=>'999','price_old'=>'1000'));        
        $this->prod_mdl->update_by_id(2, array('sku'=>'Change2', 'quantity'=>'9999','price'=>'9999','price_old'=>'10000'));
        
        // Update products from Excel
        $this->p_ex->updateProductsFromExcel($this->p_ex->GetTmpDir().$filename);
        
        // Check if products where updated:
        $product1 = $this->prod_mdl->select_by_id(1);
        $product2 = $this->prod_mdl->select_by_id(2);
                
        $this->assertEqual($this->prod_mdl->test_data[0], $product1);
        $this->assertEqual($this->prod_mdl->test_data[1], $product2);        
    }
    
    function TestupdateProductsFromExcel_UpdateStatus() {
        // Create Excel file using BackupExcel method
        $filename = 'products_test.xls';
        $this->p_ex->BackupExcel($filename);
        
        // Status mustn't be changed
        $this->art_mdl->update_by_id(1, array('statut'=>'prepa')); // In Excel file quantity is > 0 - status must be changed
        $this->art_mdl->update_by_id(4, array('statut'=>'publie')); // In Excel file quantity is < 0 - status must be changed
        //$this->prod_mdl->update_by_id(1, array('quantity'=>'0'));      
        //$this->prod_mdl->update_by_id(4, array('quantity'=>'999'));        
        
        $old_status = $this->model->UpdateStatus; 
        $this->p_ex->UpdateStatus = true;        
        $this->p_ex->updateProductsFromExcel($this->p_ex->GetTmpDir().$filename);
        
        // Check if articles statuses where updated:
        $article1 = $this->art_mdl->select_by_id(1);
        $article4 = $this->art_mdl->select_by_id(4);
        
        $this->assertEqual('publie', $article1['statut']);
        $this->assertEqual('prepa', $article4['statut']);
        
        // Status mustn't be changed
        $this->p_ex->UpdateStatus = false;
        $this->art_mdl->update_by_id(1, array('statut'=>'prepa')); // In Excel file quantity is > 0, but status mustn't be changed
        $this->p_ex->updateProductsFromExcel($this->p_ex->GetTmpDir().$filename);
        $article1 = $this->art_mdl->select_by_id(1);
        $this->assertEqual('prepa', $article1['statut']);
        
        $this->p_ex->UpdateStatus = $old_status;        
    }
    
    function TestupdateProductsFromExcel_Insert() {
        // Create Excel file using BackupExcel method
        $filename = 'products_test.xls';
        $this->p_ex->BackupExcel($filename);
        
        // We will delete article and product 1, so it must be created automatically when updating from Excel
        $this->art_mdl->delete_by_id(1);
        $this->prod_mdl->delete_by_id(1);
        $this->p_ex->updateProductsFromExcel($this->p_ex->GetTmpDir().$filename, 'id_article', true);
        // New article id will be auto incremented to 5        
        // To avoid problems, we will check only updated fields
        $product1 = $this->prod_mdl->select_by_id(5);
        $product_check = array();
        $product_check['id_article'] = 5;
        $product_check['price'] = $this->prod_mdl->test_data[0]['price'];
        $product_check['priceold'] = $this->prod_mdl->test_data[0]['priceold'];
        $product_check['sku'] = $this->prod_mdl->test_data[0]['sku'];
        $product_check['quantity'] = $this->prod_mdl->test_data[0]['quantity'];
        
        $product1 = array('id_article'=>$product1['id_article'], 
                                                 'price'=>$product1['price'],
                                                 'priceold'=>$product1['priceold'],
                                                 'sku'=>$product1['sku'],
                                                 'quantity'=>$product1['quantity']
                                                    );        
        $this->assertEqual($product_check, $product1);
    }
    
    function TestupdateProductsFromExcel_UpdateBySku() {
        // Create Excel file using BackupExcel method
        $filename = 'products_test.xls';
        $this->p_ex->BackupExcel($filename);
        
        // Update article and product in database so later we can see changes from Excel
        // We will update by sku, therefore we won't change sku!!!
        $this->art_mdl->update_by_id(1, array('titre'=>'Article 1111'));        
        $this->prod_mdl->update_by_id(1, array(//'sku'=>'Change1',
                                               'quantity'=>'999','price'=>'999','price_old'=>'1000'));
        
        $this->p_ex->updateProductsFromExcel($this->p_ex->GetTmpDir().$filename, 'sku');
        
        // Check if product was updated:
        $product1 = $this->prod_mdl->select_by_id(1);        
        $this->assertEqual($this->prod_mdl->test_data[0], $product1);
    }
}
